package com.goldsprite.gsgecs.entities;

import java.util.*;

import com.goldsprite.gsgecs.GameLoop;
import com.goldsprite.gsgecs.components.IGameComponent;
import com.goldsprite.gsgecs.systems.GameObjectManager;

public class GameObject extends GameLoop implements IGameObject {

	private final Map<Class<? extends IGameComponent>, List<IGameComponent>> components = new HashMap<>();
	private final String uuid;

	/**
	 * 私有构造函数禁止外部实例化, 请使用Entity.instantiate()实例化实体
	 * @param uuid 实体唯一标识
	 */
	private GameObject(String uuid) {
		this.uuid = uuid;
		GameObjectManager.getInstance().instantiateEntity(this);
	}

	public static GameObject instantiate(){
		return new GameObject(GameObjectManager.getInstance().getUuidSeed());
	}

	@Override
	public <T extends IGameComponent> void addComponent(T component) {
		addComponent(component.getClass());
	}

	@Override
	public void addComponent(Class<? extends IGameComponent> componentClass) {
		try {
			components.computeIfAbsent(componentClass, k -> new ArrayList<>()).add(componentClass.newInstance());
		} catch (InstantiationException | IllegalAccessException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public <T extends IGameComponent> void removeComponent(T component) {
		removeComponent(component.getClass());
	}

	@Override
	public void removeComponent(int index, Class<? extends IGameComponent> componentClass) {
		List<IGameComponent> list = components.get(componentClass);
		if (list != null && !list.isEmpty()) {
			if(list.size() == 1) removeComponents(componentClass);
			else if(index >= 0 && index < list.size()) list.remove(index);
			else throw new IllegalArgumentException("移除失败, 没有索引为"+index+"的组件");
		}
		else throw new IllegalArgumentException("未找到组件类型: " + componentClass.getName());
	}

	@Override
	public void removeComponent(Class<? extends IGameComponent> componentClass) {
		List<IGameComponent> list = components.get(componentClass);
		if (list != null && !list.isEmpty()) {
			if(list.size() == 1) removeComponents(componentClass);
			else list.remove(list.size()-1); // 移除该类型的第一个组件
		}
		else {
			throw new IllegalArgumentException("未找到组件类型: " + componentClass.getName());
		}
	}

	@Override
	public void removeComponents(Class<? extends IGameComponent> componentClass) {
		if (!components.containsKey(componentClass)) {
			throw new IllegalArgumentException("未找到组件类型: " + componentClass.getName());
		}
		components.remove(componentClass); // 仅移除指定类型的组件
	}

	@Override
	public <T extends IGameComponent> T getComponent(int index, Class<T> componentClass) {
		List<IGameComponent> list = components.get(componentClass);
		if (list != null && !list.isEmpty()) {
			if(index >= 0 && index < list.size())
				return componentClass.cast(list.get(index));
		}
		return null; // 如果找不到组件，返回 null
	}

	@Override
	public <T extends IGameComponent> T getComponent(Class<T> componentClass) {
		return getComponent(0, componentClass); // 获取第一个组件
	}

	@Override
	public List<? extends IGameComponent> getComponents(Class<? extends IGameComponent> componentClass) {
		if(components.containsKey(componentClass)) return components.get(componentClass);
		return null;
	}

	public String getUuid() {
		return uuid;
	}
}
